package live.zs;

import io.smallrye.mutiny.Uni;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.Response;
import live.zs.entity.Fruit;
import org.hibernate.reactive.mutiny.Mutiny;
import org.jboss.resteasy.reactive.RestPath;

import java.util.List;

/**
 * @author madison
 * @description
 * @date 2022/2/6 17:20
 */
@Path("fruits")
@ApplicationScoped
@Produces("application/json")
@Consumes("application/json")
public class FruitMutinyResource {
    @Inject
    Mutiny.SessionFactory sf;

    @GET
    public Uni<List<Fruit>> get() {
        return sf.withTransaction((s, t) -> s
                .createNamedQuery("Fruits.findAll", Fruit.class)
                .getResultList());
    }


    @GET
    @Path("{id}")
    public Uni<Fruit> getSingle(@RestPath Integer id) {
        return sf.withTransaction((s, t) -> s.find(Fruit.class, id));
    }

    @POST
    public Uni<Response> create(Fruit fruit) {
        if (fruit == null || fruit.getId() != null) {
            throw new WebApplicationException("Id was invalidly set on request.", 422);
        }
        return sf.withTransaction((s, t) -> s.persist(fruit)
                .replaceWith(() -> Response.ok().status(Response.Status.CREATED).build()));
    }

    @PUT
    @Path("{id}")
    public Uni<Response> update(@RestPath Integer id, Fruit fruit) {
        if (fruit == null || fruit.getName() == null) {
            throw new WebApplicationException("Fruit name was not set on request.", 422);
        }
        return sf.withTransaction((s, t) -> s.find(Fruit.class, id)
                .onItem().ifNotNull().invoke(entity -> entity.setName(fruit.getName()))
                .onItem().ifNotNull().transform(entity -> Response.ok(entity).build())
                .onItem().ifNull()
                .continueWith(() -> Response.ok().status(Response.Status.NOT_FOUND).build()));
    }

    @DELETE
    @Path("{id}")
    public Uni<Response> delete(@RestPath Integer id) {
        return sf.withTransaction((s, t) ->
                s.find(Fruit.class, id)
                        .onItem().ifNotNull().transformToUni(entity ->
                                s.remove(entity).replaceWith(() ->
                                        Response.ok().status(Response.Status.NO_CONTENT).build()
                                ))
                        .onItem().ifNull().continueWith(() -> Response.ok().status(Response.Status.NOT_FOUND).build()));
    }
}
